#include "slotspin.h"

#include "lib.h"
#include "log.h"

SlotSpin::SlotSpin()
{
    m_stopCount = 0;
    m_multibankBet = 0;
    m_multibankPayout = 0;
    m_spinComplete = false;
    m_spinSaved = false;
    m_spinSent = false;
    m_stops = (uint8 *) 0;
    m_gameNum = 0;
    m_bonusGameType = 0;
}

void
SlotSpin::setStops(uint8 stopCount, uint8 *stops)
{
    if ( m_stops != (uint8 *) 0 )
    {
        delete [] m_stops;
    }

    m_stopCount = stopCount;
    m_stops = new uint8[m_stopCount];
    for ( uint8 i = 0; i < m_stopCount; i++ )
    {
        m_stops[i] = stops[i];
    }

}

SlotSpin::~SlotSpin()
{
    delete [] m_stops;

    while ( m_spinLines.size() > 0 )
    {
        SpinLine *spinLine = m_spinLines.back();
        delete spinLine;
        m_spinLines.pop_back();
    }

    while ( m_bonusGames.size() > 0 )
    {
        BonusGame *bonusGame = m_bonusGames.back();
        delete bonusGame;
        m_bonusGames.pop_back();
    }

    clearScatters();
}


uint8
SlotSpin::getSpinLineCount() const
{
    return m_spinLines.size();
}


        
uint8 
SlotSpin::getStopCount() const
{
    return m_stopCount;
}
        
const uint8 *
SlotSpin::getStops() const
{
    return m_stops;
}

        
uint8 
SlotSpin::getBonusGameType() const
{
    return m_bonusGameType;
}
        
void 
SlotSpin::setBonusGameType(uint8 bonusGameType)
{
    m_bonusGameType = bonusGameType;
}

        
BonusGame *
SlotSpin::findBonusGame(uint8 bonusGameNum) const
{
    BonusGame *bonusGame = (BonusGame *) 0;

    for ( uint8 i = 0; m_bonusGames.size() > i; i++ )
    {
        bonusGame = m_bonusGames[i];

        if ( bonusGame->bonusgamenum == bonusGameNum )
        {
            break;
        }
        else
        {
            bonusGame = (BonusGame *) 0;
        }
    }

    return bonusGame;
}

// kharmon.  07-25-07.  #19498.  Need to update fun balance with bonus wins.
BonusGame *SlotSpin::getBonusGame(int32 nIndex) const
{
    BonusGame *pBonusGame = NULL;

    if ( nIndex >= 0 && nIndex < (int32) m_bonusGames.size() )
    {
        pBonusGame = m_bonusGames[nIndex];
    }

    return pBonusGame;
}

// kharmon.  07-25-07.  #19498.  Need to update fun balance with bonus wins.
int32 SlotSpin::getNumBonusGames() const
{
    return m_bonusGames.size();
}

        
void 
SlotSpin::addBonusGame(uint8 bonusgamenum, uint8 playerchoice, int32 winresult)
{
    BonusGame *bonusGame = findBonusGame(bonusgamenum);

    if ( bonusGame == (BonusGame *) 0 )
    {
        bonusGame = new BonusGame();
        bonusGame->bonusgamenum = bonusgamenum;
        bonusGame->playerchoice = playerchoice;
        bonusGame->winresult = winresult;

        m_bonusGames.push_back(bonusGame);
    }
    else
    {
        /**
         * Duplicate lineid.
         */
		Log::msgWarning("Trying to create a bonus game, but there's already one there: %d", this->m_gameNum);
 //       ASSERT(0);
    }
}

        
int32 
SlotSpin::getTotalBonusPayoutAmount()
{
    int32 payout = 0;

    for ( uint8 i = 0; i < m_bonusGames.size(); i++ )
    {
        BonusGame *bonusGame = m_bonusGames[i];
        payout += bonusGame->winresult;
    }

    return payout;
}



SpinLine *
SlotSpin::findSpinLine(uint8 lineid) const
{
    SpinLine *spinLine = (SpinLine *) 0;

    for ( uint8 i = 0; m_spinLines.size() > i; i++ )
    {
        spinLine = m_spinLines[i];

        if ( spinLine->lineid == lineid )
        {
            break;
        }
        else
        {
            spinLine = (SpinLine *) 0;
        }
    }

    return spinLine;
}

        
       
void 
SlotSpin::setJackpotAmount(uint8 lineid, int32 jackpotamount)
{
    SpinLine *spinLine = findSpinLine(lineid);

    if ( spinLine != (SpinLine *) 0 )
    {
        spinLine->payoutamount = jackpotamount;
        spinLine->jackpot = true;
    }
    else
    {
        /**
         * No line allocated for this payout.
         */
        ASSERT(0);
    }
}


void
SlotSpin::setPayoutAmount(uint8 lineid, int32 payoutamount, bool8 jackpot, uint8 payouttypeid)
{
    SpinLine *spinLine = findSpinLine(lineid);

    if ( spinLine != (SpinLine *) 0 )
    {
        spinLine->payoutamount = payoutamount;
        spinLine->jackpot = jackpot;
        spinLine->payouttypeid = payouttypeid;
    }
    else
    {
        /**
         * No line allocated for this payout.
         */
        ASSERT(0);
    }
}

void
SlotSpin::addLine(uint8 lineid)
{
    SpinLine *spinLine = findSpinLine(lineid);

    if ( spinLine == (SpinLine *) 0 )
    {
        spinLine = new SpinLine();
        spinLine->jackpot = false;
        spinLine->lineid = lineid;
        spinLine->payoutamount = 0;
        spinLine->payouttypeid = 0;

        m_spinLines.push_back(spinLine);
    }
    else
    {
        /**
         * Duplicate lineid.
         */
        ASSERT(0);
    }

}

void
SlotSpin::setSpinComplete(bool8 flag)
{
    m_spinComplete = flag;
}
        
bool8
SlotSpin::isSpinComplete()
{
    return m_spinComplete;
}


void
SlotSpin::setSpinSent(bool8 flag)
{
    m_spinSent = flag;
}
        
bool8
SlotSpin::isSpinSent()
{
    return m_spinSent;
}


void
SlotSpin::setSpinSaved(bool8 flag)
{
    m_spinSaved = flag;
}
        
bool8
SlotSpin::isSpinSaved()
{
    return m_spinSaved;
}


void
SlotSpin::setMultibankPayout(int32 payout)
{
    m_multibankPayout = payout;
}

void
SlotSpin::setMultibankBet(int32 bet)
{
    m_multibankBet = bet;
}

void
SlotSpin::setBet(uint8 bet)
{
    m_bet = bet;
}
        
SpinLine *
SlotSpin::getSpinLineAt(uint8 index)
{
    SpinLine *spinLine = (SpinLine *) 0;

    if ( index < m_spinLines.size() )
    {
        spinLine = m_spinLines[index];
    }
    else
    {
        /**
          * lineid too large.
          */
		Log::msgWarning("getSpinLineAt: %d", index);
//        ASSERT(0);
    }

    return spinLine;
}

       
SpinLine *
SlotSpin::getSpinLineByLineId(uint8 lineid)
{
    return findSpinLine(lineid);
}

int32
SlotSpin::getMultibankBet() const
{
    return m_multibankBet;
}

int32
SlotSpin::getMultibankPayout() const
{
    return m_multibankPayout;
}



uint8 
SlotSpin::getBet() const
{
    return m_bet;
}
        
bool8 
SlotSpin::getJackpot()
{
    bool8 jackpot = false;


    for (uint8 lineid = 0; !jackpot && lineid < m_spinLines.size(); lineid++ )
    {
        jackpot  = getSpinLineAt(lineid)->jackpot;
    }

    return jackpot;
}


uint16 
SlotSpin::getTotalBet() const
{
    return m_bet * m_spinLines.size();
}
        
int32
SlotSpin::getTotalPayoutAmount()
{
    return getTotalSpinPayoutAmount() + getTotalBonusPayoutAmount();
}


int32
SlotSpin::getTotalSpinPayoutAmount()
{
    int32 payoutamount = 0;
    for ( uint8 i = 0; i < m_spinLines.size(); i++ )
    {
        SpinLine *spinLine = m_spinLines[i];
        payoutamount += spinLine->payoutamount;
    }

    return payoutamount;
}
        


        
void 
SlotSpin::setGameNum(int32 gameNum)
{
    m_gameNum = gameNum;
}

int32
SlotSpin::getGameNum() const
{
    return m_gameNum;
}

void 
SlotSpin::addScatter( int32 scatterposition, int32 payoutamount, bool8 jackpot, uint8 payouttypeid )
{
    SlotScatter* pScatter = findScatter(payouttypeid);

    if ( pScatter == NULL )
    {
        pScatter = new SlotScatter();
        pScatter->scatterposition = scatterposition;
        pScatter->payoutamount = payoutamount;
        pScatter->jackpot = jackpot;
        pScatter->payouttypeid = payouttypeid;

        m_scatters.push_back(pScatter);
    }
    else
    {
        /**
         * Duplicate lineid.
         */
        ASSERT(0);
    }
}

void 
SlotSpin::clearScatters()
{
    while ( m_scatters.size() > 0 )
    {
        SlotScatter *pScatter = m_scatters.back();
        delete pScatter;
        m_scatters.pop_back();
    }

    m_scatters.clear();
}

uint8 
SlotSpin::getNumScatters() const
{
    return m_scatters.size();
}

SlotScatter* 
SlotSpin::getScatter(uint8 nIndex) const
{
    SlotScatter* pScatter = NULL;

    if ( nIndex >= 0 && nIndex < m_scatters.size() )
    {
        pScatter = m_scatters[nIndex];
    }

    return pScatter;
}

SlotScatter*
SlotSpin::findScatter(uint8 payouttypeid) const
{
    SlotScatter* pScatter = NULL;

    for (uint8 i = 0; i<m_scatters.size(); i++ )
    {
        if ( m_scatters[i]->payouttypeid == payouttypeid )
        {
            pScatter = m_scatters[i];
            break;
        }
    }

    return pScatter;
}

